package thread;

/**
 * date: 2023-2-13
 * 懒汉模式的 单例模式 安全版本 的实现
 * 懒汉模式的实例不是类加载的时候创建，而是真正第一次使用的时候，才去创建（如果不用，就不创建了）
 *
 */

class SingletonLazy {
    /*  volatile 两个功能：
        1、解决内存可见性
        2、禁止指令重排序
     */
    private volatile static SingletonLazy instance = null;

    public static SingletonLazy getInstance() {
        /*  两个 if 目的：
            1、第一个负责判定是否要加锁
            2、第二个负责判定是否要创建对象
            加锁操作可能会引起线程阻塞，当执行到锁结束之后，执行到第二个 if 的时候，第二个if和第一个if之间
            可能相隔了很久时间，程序运行内部的状态、变量的值，都可能已经发生了很大的变化
         */
        if (instance == null) { // 判定是否要加锁
            synchronized (SingletonLazy.class) { // 满足 instance == null 之后才真正加锁
                if(instance == null) { // 判定是否要创建对象
                    instance = new SingletonLazy();  // 真正第一次使用的时候，才去创建
                }
            }
        }
        return instance;
    }

    private SingletonLazy() {}
}
public class ThreadDemo20 {
    public static void main(String[] args) {
        SingletonLazy s = SingletonLazy.getInstance();
        SingletonLazy s2 = SingletonLazy.getInstance();
        System.out.println(s == s2);
    }
}
